import CryptoJS from 'crypto-js'

function ltrim(str: string) {
  const reg = /^\s+/g
  return str.replace(reg, '')
}

// 去除右侧空格

function rtrim(str: string) {
  const reg = /\s+$/g
  return str.replace(reg, '')
}

// 去除两侧的空格

function trim(str: string) {
  const reg = /^\s+|\s+$/g
  return str.replace(reg, '')
}
const nvl = (v: any): string => {
  if (v) {
    return trim(v.toString())
  } else {
    return ''
  }
}
const deepCopy = (obj: any) => {
  return JSON.parse(JSON.stringify(obj))
}
// 生成随机字符串
function getNonceStr(type: any): string {
  // CryptoJS.enc.Hex // 16进制
  // CryptoJS.enc.Utf8 // Utf8
  type = type || CryptoJS.enc.Hex
  return CryptoJS.lib.WordArray.random(128 / 8).toString(type)
}
// 加密的方法
function encryptAES(encryptObj: any, secretKey: string): any {
  // 加密的api方法(解密时,秘钥和后面的参数配置需对应)
  // CryptoJS.AES.encrypt('待加密的字符串', '加密秘钥', {
  //   iv: CryptoJS.enc.Utf8.parse('ABCDEF1234123412'), // 十六位十六进制数作为密钥偏移量
  //   mode: CryptoJS.mode.CBC, // 支持的模式CBC/CFB/CTR//OFB/ECB
  //   padding: CryptoJS.pad.Pkcs7 // 填充方案Pkcs7/Iso97971/AnsiX923/Iso10126/ZeroPadding/NoPadding
  // })
  if (!encryptObj || !secretKey) {
    return null
  }
  let encryptedString = null
  const iv_hex_md5 = CryptoJS.MD5(secretKey).toString(CryptoJS.enc.Hex) // 秘钥进行MD5加密并转换成16进制
  const iv = iv_hex_md5.substr(8, 16)
  const secretKey_hex_md5 = iv_hex_md5.substr(0, 16)
  if (typeof encryptObj === 'string') {
    encryptedString = CryptoJS.AES.encrypt(encryptObj, CryptoJS.enc.Utf8.parse(secretKey_hex_md5), {
      iv: CryptoJS.enc.Utf8.parse(iv),
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7
    }).toString()
  } else if (typeof encryptObj === 'object') {
    const dataString = JSON.stringify(encryptObj)
    encryptedString = CryptoJS.AES.encrypt(dataString, CryptoJS.enc.Utf8.parse(secretKey_hex_md5), {
      iv: CryptoJS.enc.Utf8.parse(iv),
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7
    }).toString()
  }
  return encryptedString
}
// 解密的方法
const decryptAES = function (decryptObj: string, secretKey: string): any {
  if (!decryptObj || !secretKey) {
    return null
  }
  let decryptedString = null
  const iv_hex_md5 = CryptoJS.MD5(secretKey).toString(CryptoJS.enc.Hex) // 秘钥进行MD5加密并转换成16进制
  const iv = iv_hex_md5.substr(8, 16)
  const secretKey_hex_md5 = iv_hex_md5.substr(0, 16)
  const bytesObj = CryptoJS.AES.decrypt(decryptObj, CryptoJS.enc.Utf8.parse(secretKey_hex_md5), {
    iv: CryptoJS.enc.Utf8.parse(iv),
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  })
  decryptedString = bytesObj.toString(CryptoJS.enc.Utf8)
  return decryptedString
}
function getMD5String(str: string | undefined) {
  if (str) {
    return CryptoJS.MD5(str).toString().toUpperCase()
  } else {
    return CryptoJS.MD5('').toString().toUpperCase()
  }
}
// 获取assets静态资源
const getFileSrc = function (url: string) {
  return new URL(url, import.meta.url).href
}
const $toTree = function (data: Array<any>, toArray: boolean): Array<any> {
  let dataArray = [] as Array<any>
  data.forEach(function (item) {
    if (toArray) {
      if (!item.p_function_no) {
        const objTem = {
          function_name: item.function_name,
          function_no: item.function_no,
          function_url: item.function_url,
          p_function_no: item.p_function_no,
          icon: item.icon,
          is_menu: item.is_menu,
          sort_num: item.sort_num,
          action: item.action,
          target: item.target,
          url_type: item.url_type
        }
        Object.assign(objTem, item)
        dataArray.push(objTem)
      }
    } else {
      if (!item.p_function_no) {
        const objTem = {
          function_name: item.function_name,
          function_no: item.function_no,
          function_url: item.function_url,
          p_function_no: item.p_function_no,
          sortnum: item.sort_num,
          action: item.action,
          target: item.target,
          icon: item.icon,
          url_type: item.url_type
        }
        Object.assign(objTem, item)
        dataArray.push(objTem)
      }
    }
  })
  return dataToTree(data, dataArray, toArray)
}
function dataToTree(data: Array<any>, dataArray: Array<any>, toArray: boolean): Array<any> {
  dataArray.forEach(function (pItem) {
    const childrenArray = [] as Array<any>
    data.forEach(function (sItem) {
      if (toArray) {
        if (sItem.p_function_no === pItem.function_no) {
          var objTem = {
            function_name: sItem.function_name,
            function_no: sItem.function_no,
            function_url: sItem.function_url,
            p_function_no: sItem.p_function_no,
            icon: sItem.icon,
            is_menu: sItem.is_menu,
            sort_num: sItem.sort_num,
            action: sItem.action,
            target: sItem.target,
            url_type: sItem.url_type
          }
          Object.assign(objTem, sItem)
          childrenArray.push(objTem)
        }
      } else {
        if (sItem.p_function_no === pItem.function_no) {
          var objTems = {
            function_name: sItem.function_name,
            function_no: sItem.function_no,
            function_url: sItem.function_url,
            p_function_no: sItem.p_function_no,
            sortnum: sItem.sort_num,
            action: sItem.action,
            icon: sItem.icon,
            target: sItem.target,
            url_type: sItem.url_type
          }
          Object.assign(objTems, sItem)
          childrenArray.push(objTems)
        }
      }
    })
    if (toArray) {
      if (childrenArray.length > 0) {
        pItem.children = childrenArray
      }
    } else {
      pItem.children = childrenArray
    }

    if (childrenArray.length > 0) {
      dataToTree(data, childrenArray, toArray)
    }
  })
  return dataArray
}
const getFileNameFromUrl = (filePath: string) => {
  return nvl(filePath.split(/[\\/]/).pop())
}
const dataURLtoBlob = (dataurl) => {
  var arr = dataurl.split(','),
    mime = arr[0].match(/:(.*?);/)[1],
    bstr = atob(arr[1]),
    n = bstr.length,
    u8arr = new Uint8Array(n)
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n)
  }
  return new Blob([u8arr], { type: mime })
}
const dateFormat = (date, fmt) => {
  let ret
  const opt = {
    'Y+': date.getFullYear().toString(), // 年
    'M+': (date.getMonth() + 1).toString(), // 月
    'd+': date.getDate().toString(), // 日
    'H+': date.getHours().toString(), // 时
    'm+': date.getMinutes().toString(), // 分
    's+': date.getSeconds().toString(), // 秒
    'S+': date.getMilliseconds()
    // 有其他格式化字符需求可以继续添加，必须转化成字符串
  }
  for (let k in opt) {
    ret = new RegExp('(' + k + ')').exec(fmt)
    if (ret) {
      fmt = fmt.replace(ret[1], ret[1].length == 1 ? opt[k] : opt[k].padStart(ret[1].length, '0'))
    }
  }
  return fmt
}
const base64ToFile = (base64, fileName) => {
  let arr = base64.split(',')
  let mime = arr[0].match(/:(.\*?);/)[1]
  let ext = mime.split('/')[1]
  let bstr = atob(arr[1])
  let n = bstr.length
  let u8arr = new Uint8Array(n)
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n)
  }
  return new File([u8arr], fileName + '.' + ext, { type: mime })
}
const sleep = (timeout: number) => {
  return new Promise((resolve) => setTimeout(resolve, timeout))
}
export default {
  getNonceStr,
  encryptAES,
  decryptAES,
  getMD5String,
  getFileSrc,
  $toTree,
  nvl,
  trim,
  ltrim,
  rtrim,
  deepCopy,
  getFileNameFromUrl,
  dataURLtoBlob,
  dateFormat,
  base64ToFile,
  sleep
}
